from typing import Union
from fastapi import FastAPI
import _thread
import requests
import time
from db_connect import overall,pv_SELECT
import uvicorn
from logger import getLogger
from epics import PV
import numpy as np

feedback_url_0 = r"http://192.168.6.124:9000/api/modeconf/feedback/"
feedback_url_1 = r"http://192.168.6.124:9000/api/modeconf/feedback/?source=1"
#feedback_url = r"https://modeconfig-api.gisbook.cn/api/modeconf/feedback/"
# overall_url = r"https://modeconfig-api.gisbook.cn/api/modeconf/overall/"
app = FastAPI()

logger = getLogger("mode")
pv_status = PV("TEST:Mode:status")
pv_info = PV("TEST:Mode:info")
pv_dict = {}

def feedback(data,source):
    logger.debug(data)
    try:
        if source == 1:
            res = requests.post(url=feedback_url_1,data=data)
        else:
            res = requests.post(url=feedback_url_0,data=data)
        if res.json()["status"] == 1:
            return True
        else:
            return False
    except Exception as e:
        logger.error(e)
    

def Mode_switching(uuid,task_id,res_data,source):
    pv_info.put("Mode Switch is run")
    logger.debug("分总体名:\t"+str(res_data["data"]['overallName']))
    logger.debug("分总体描述:\t"+str(res_data["data"]['overallDesc']))
    _Flag = True
    F_pv_list = []
    now_pv = ""
    Ver_msg = "Version check is successful"
    try:
        for pv_name,value in res_data["data"]['Lock']['version'].items():
            #logger.debug(str(pv_name)+" : 正在写入\t"+str(value))
            now_pv = pv_name
            if pv_name in pv_dict.keys():
                status = pv_dict[pv_name].put(float(value))
            else:
                pv = PV(pv_name)
                pv_dict[pv_name] = pv
                time.sleep(0.01)
                status = pv.put(float(value))
            if status == 1:
                pass
                logger.debug(pv_name+" 操作成功")
            else:
                Ver_msg = "Version check is failed"
                _Flag = False
                break
        for modeConfs in res_data["data"]['subSystems'].values():
            #logger.debug("子系统名:\t"+str(subSystems["subName"]))
            #logger.debug("子系统描述:\t"+str(subSystems["subDesc"]))
            #logger.debug(str(modeConfs["pv"])+" : 正在写入\t"+str(modeConfs["defaultValue"]))
            now_pv = modeConfs["pv"]
            if modeConfs["pv"] in pv_dict.keys():
                status = pv_dict[modeConfs["pv"]].put(float(modeConfs["defaultValue"]))
            else:
                pv = PV(modeConfs["pv"])
                pv_dict[modeConfs["pv"]] = pv
                time.sleep(0.01)
                status = pv.put(float(modeConfs["defaultValue"]))
            if status == 1:
                pass
                logger.debug(modeConfs["pv"]+" 操作成功")
            else:
                F_pv_list.append(modeConfs["pv"])
                _Flag = False
        
        for pv_name,value in res_data["data"]['Lock']['data'].items():
            try:
                now_pv = pv_name
                #logger.debug(str(pv_name)+" : 正在写入\t"+"".join(value))
                if pv_name in pv_dict.keys():
                    status = pv_dict[pv_name].put(np.array(value).astype(np.int16))
                else:
                    pv = PV(pv_name)
                    pv_dict[pv_name] = pv
                    time.sleep(0.01)
                    status = pv.put(np.array(value).astype(np.int16))
                if status == 1:
                    pass
                    logger.debug(pv_name+" 操作成功")
                else:
                    F_pv_list.append(pv_name)
                    _Flag = False
            except:
                F_pv_list.append(str(pv_name))
                _Flag = False
                continue
    except Exception as e:
        data = {
                    "uuid" : uuid,
                    "task_id" : task_id,
                    "result" : 0,
                    "explain" : now_pv + str(e)
            }
        pv_status.put(0)
        pv_info.put(str(e))
        feedback(data,source)
        return
    if _Flag:
        data = {
                "uuid" : uuid,
                "task_id" : task_id,
                "result" : 1,
                "explain" : "切换完成"
            }
        feedback(data,source)
        pv_status.put(1)
        pv_info.put("Mode Switch is complate")
        return
    else:
        data = {
                "uuid" : uuid,
                "task_id" : task_id,
                "result" : 0,
                "explain" : "version: {} ,PV: {} is connection failed".format(Ver_msg," and ".join(F_pv_list))
                }
        feedback(data,source)
        pv_status.put(0)
        pv_info.put(str(data["explain"]))
        return

@app.get("/api/modeconf/notice")
async def read_item(uuid: Union[str,None] = None, task_id: Union[str,None] = None,source : Union[int,None] = None):
    pv_info.put("")
    if uuid == None or task_id == None:
        logger.error({"status":0,"msg":"参数缺失"})
        data = {
                    "uuid" : uuid,
                    "task_id" : task_id,
                    "result" : 0,
                    "explain" : "参数缺失"
            }
        feedback(data,source)
        pv_status.put(0)
        pv_info.put("Parameter is missing")
        return {"status":0,"msg":"参数缺失"}
    try:
        res = overall(task_id = task_id.replace(" ","") , uuid = uuid.replace(" ",""))
        if res["status"] == 1:
            pv_status.put(0)
            pv_info.put("Data retrieval successful")
            _thread.start_new_thread(Mode_switching,(uuid,task_id,res,source))
            logger.debug({"status":1,"uuid": uuid,"task_id": task_id,"msg": "OK"})
            return {"status":1,"uuid": uuid,"task_id": task_id,"msg": "OK"}
        else:
            data = {
                    "uuid" : uuid,
                    "task_id" : task_id,
                    "result" : 0,
                    "explain" : res["msg"]
            }
            feedback(data,source)
            return res
    except Exception as e:
        logger.error(str(e))
        pv_status.put(0)
        pv_info.put(str(e))
    


if __name__ == "__main__":
    print("请不要关闭终端...")
    uvicorn.run(app="main:app",host="0.0.0.0",port=8099,reload=False)
    

